package com.sky.service.impl;

import com.sky.context.BaseContext;
import com.sky.dto.ShoppingCartDTO;
import com.sky.entity.Dish;
import com.sky.entity.Setmeal;
import com.sky.entity.ShoppingCart;
import com.sky.mapper.DishMapper;
import com.sky.mapper.SetmealMapper;
import com.sky.mapper.ShoppingcartMapper;
import com.sky.service.ShoppingcartService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.List;

@Service
@Slf4j
public class ShoppingcartServiceImpl implements ShoppingcartService {

    @Autowired
    private ShoppingcartMapper shoppingcartMapper;

    @Autowired
    private DishMapper dishMapper;

    @Autowired
    private SetmealMapper setmealMapper;


    @Override
    public void add(ShoppingCartDTO shoppingCartDTO) {
        //构造ShoppingCart封装请求参数，因为它包含用户的id。
        ShoppingCart shoppingCart = new ShoppingCart();
        //对象属性拷贝：dishId、setmealId、dishFlavor
        BeanUtils.copyProperties(shoppingCartDTO, shoppingCart);
        //设置用户id：用户端每次发送请求都会携带token，通过JwtTokenUserInterceptor拦截器去解析
        //这个token,解析出来的用户id和ThreadLocal进行绑定，之后在这个地方通过ThreadLocal取出来即可。
        Long userId = BaseContext.getCurrentId();
        log.info("userId:{}", userId);
        shoppingCart.setUserId(userId);

        /**
         * 1.判断当前加入到购物车中的商品是否已经存在了:
         *    如何判断是否存在了，需要去查询，那要查询的话是根据什么条件去查询呢？？？
         *    购物车添加的是套餐：根据套餐id和用户id，因为不同的用户有自己的购物车数据，需要通过user_id来区分出来。
         *        eg：select * from shopping_cart where user_id = ? and setmeal_id = xxx;
         *           结果有可能查出来有可能查不出来，之后按照查不出出来的情况分别判断。
         *    购物车添加的是菜品：除了菜品id、用户id 还需要根据口味数据查询，因为对于同一个菜品来说如果它的口味
         *                    不一样的话，在购物车里面也是不同的2条数据，你就不能简单地把这个数量给加1了，所以
         *                    口味也是一个查询字段。
         *       eg：select * from shopping_cart where user_id = ? and dish_id = xxx and dish_flavor = xx;
         *
         *    不需要分别写这2条sql，只需要使用一条动态的sql来动态拼接条件即可。
         *
         */
        List<ShoppingCart> shoppingCartList = shoppingcartMapper.list(shoppingCart);

        log.info("购物车:{}", shoppingCartList);

        //2.如果已经存在，就更新数量，数量加1
        //注意：当前方法返回值虽然是一个list集合，但是按照当前设置的这些条件来说，实际上是不可能查出来多条数据的。
        //     根据用户id再加上菜品id或者套餐id来查询，对于相同的商品只需要修改数量就可以了，不会说在重新插入一条数据。
        //     所以说按照当前这些条件去查询的话只有2种结果：查不到或者查到之后只有一条数据。
        if(shoppingCartList != null && shoppingCartList.size() > 0) {
            shoppingCart = shoppingCartList.get(0);//取出来第一条数据 也是唯一的一条数据。
            shoppingCart.setNumber(shoppingCart.getNumber() + 1);//在原先的数量基础上加1，之后执行update语句。


        // update shopping_cart set number = ? where id = ?
        //因为是从数据库里面查出来的，所以cart里面一定是有id的。
        shoppingcartMapper.updateNumberById(shoppingCart);
        }else{
            //3.如果不存在，需要插入一条购物车数据
            //思路分析：ShoppingCart实体类插入数据时除了上面设置的参数，还需要name名称、价格amount、图片
            //        的路径image，这几个参数前端并没有给我们提交过来 所以自己手动查询出来。
            //   情况1：如果提交的是一个菜品，需要在菜品表里面去查询 菜品的名称 价格 和图片路径。
            //   情况2：如果提交的是一个套餐，需要在套餐表里面去查询 套餐的名称 价格 和图片路径。
            // 所以说呢我们在这个地方啊需要做什么事情啊，先来判断一下你这一次添加到购物车中的这个商品，具体是
            //     一个菜品还是一个套餐，因为只有知道了是一个菜品还是一个套餐才能知道具体去查询那个表。
            //     只需要通过获取shoppingCartDTO的菜品id或套餐id来判断是否为空，就可以知道这一次添加到
            //      购物车中的商品是菜品还是套餐。

            //4.判断当前添加到购物车的是菜品还是套餐
            Long dishId = shoppingCartDTO.getDishId();
            if(dishId != null) {
                //添加到购物车的是菜品
                //dish_id(菜品id)不为空说明添加的就是菜品，不可能是套餐因为之前说过要么添加的是菜品要么是套餐，
                //   你不可能某一次添加的购物车既是菜品又是套餐。
                Dish dish = dishMapper.getById(dishId);
                shoppingCart.setName(dish.getName());
                shoppingCart.setImage(dish.getImage());
                shoppingCart.setAmount(dish.getPrice());

            }else{
                //添加到购物车的是套餐
                //这个地方不用再判断了，因为进到了else说明这个dishId一定为空，dishId为空说明
                //    这个SetmealId一定不为空。
                Setmeal setmeal = setmealMapper.getById(shoppingCartDTO.getSetmealId());
                shoppingCart.setName(setmeal.getName());
                shoppingCart.setImage(setmeal.getImage());
                shoppingCart.setAmount(setmeal.getPrice());
            }
            shoppingCart.setNumber(1);//设置数量，固定第一次插入就是1.
            shoppingCart.setCreateTime(LocalDateTime.now());//创建时间
            shoppingcartMapper.insert(shoppingCart);


        }
    }

    //删除购物车中的一个商品
    @Override
    public void sub(ShoppingCartDTO shoppingCartDTO) {
        //如果删除后number等于0，则把整条数据删除
        ShoppingCart shoppingCart = new ShoppingCart();
        BeanUtils.copyProperties(shoppingCartDTO, shoppingCart);
        Long userId = BaseContext.getCurrentId();
        shoppingCart.setUserId(userId);
        shoppingCart.setCreateTime(LocalDateTime.now());

        //查询当前购物车商品的数量
        List<ShoppingCart> shoppingCartList = shoppingcartMapper.list(shoppingCart);
        log.info("当前要删除购物车商品为:{}", shoppingCartList);
        Integer number = shoppingCartList.get(0).getNumber();
        //log.info("当前购物车商品数量:{}", number);
        if(number == 1){
            shoppingcartMapper.deleteNumber(shoppingCart);
        }else{
            //如果删除后number不等于0，则number-1
            log.info("删除后的商品数量:{}", number);
            shoppingCart.setNumber(number - 1);
            shoppingcartMapper.updateNumber(shoppingCart);

        }
    }

    //查看购物车
    @Override
    public List<ShoppingCart> list() {
        Long userId = BaseContext.getCurrentId();
        List<ShoppingCart> shoppingCartList = shoppingcartMapper.listShoppingCart(userId);
        return shoppingCartList;
    }

    //清空购物车
    @Override
    public void clean() {
        Long userId = BaseContext.getCurrentId();
        log.info("用户userId = :{}，清空购物车", userId);
        shoppingcartMapper.clean(userId);
    }
}
